/*
    完美转发的应用主要在于：
        有时候函数多层嵌套，参数在传递的过程中失去其原始类型(左值/右值...)
        std::forward<T>(arg) 可以无损地将参数传递到下一个函数。

 */

#include <iostream>
#include <utility> // std::forward

template<typename T>
T&& my_forward(typename std::remove_reference<T>::type& arg) noexcept
{
    return static_cast<T&&>(arg);
}

void process(int& x)
{
    std::cout << "Lvalue processed: " << x << std::endl;
}

void process(int&& x)
{
    std::cout << "Rvalue processed: " << x << std::endl;
}

template<typename T>
void wrapper(T&& arg) // T&& 万能引用: 可接收左值、右值
{
    process(std::forward<T>(arg)); // 通过 std::forward 完美转发参数
    // process(my_forward<T>(arg));
}

template<typename T>
void wrapper_without_forward(T arg)
{
    process(arg); // 这里的 arg 被传递为一个左值
}

int main()
{
    int a = 10;
    wrapper(a);  // 传递左值，调用 void process(int&)
    wrapper(20); // 传递右值，调用 void process(int&&)

    wrapper_without_forward(30); // 传递右值，但调用的是 void process(int&)
    return 0;
}
